package com.hustbaidu.hustmap;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Bitmap.Config;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnCreateContextMenuListener;

public class MapView extends SurfaceView implements SurfaceHolder.Callback{
	private SurfaceHolder holder;
	private Bitmap bm;
	private Bitmap mapBackground;
	private int mapChipWidth, mapChipHeight;
	private int mapChipNumX, mapChipNumY;
	private int mapChipTotalX, mapChipTotalY;
	private int mapViewWidth, mapViewHeight;
	private int currentChipX, currentChipY;
	private int offsetX, offsetY;
	private int oldOffsetX, oldOffsetY;
	
	private String mainDataPath;
	private String[][] mapChipName;
	
	public int realDistanceX, realDistanceY;
	
	public MapView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		System.out.println("MapView constructor");
		mapChipWidth = 300;
		mapChipHeight = 300;
		mapChipTotalX = 7;
		mapChipTotalY = 6;
				
		offsetX = 0;
		offsetY = 0;
		oldOffsetX = 0;
		oldOffsetY = 0;
		currentChipX = 0;
		currentChipY = 0;
		mainDataPath = "/sdcard/HustMapData";
		mapChipName = new String[mapChipTotalX][mapChipTotalY];
		realDistanceX = 0;
		realDistanceY = 0;
		initMapChip();
		
//		setFocusable(true);  
//        requestFocus();
//        setFocusable(true);
		holder = this.getHolder();
		holder.addCallback(this);	
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		mapViewWidth = width;
		mapViewHeight = height;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		System.out.println("MapView surfaceCreated");
		mapViewWidth = getWidth();
		mapViewHeight = getHeight();
		
		updateMapBackground(true);
		updateMapView();
	}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
//		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
//		return super.onTouchEvent(event);
		return true;
	}

	public void updateMapView(){
		Canvas c = holder.lockCanvas();
		c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
		
		if(offsetX < 0){
			if(currentChipX > 0){
				currentChipX--;
				updateMapBackground(false);
				realDistanceX = offsetX - oldOffsetX;
				offsetX += mapChipWidth;
			}
			else{
				offsetX = 0;
				realDistanceX = offsetX - oldOffsetX;
			}
		}
		
		if(offsetY < 0){
			if(currentChipY > 0){
				currentChipY--;
				updateMapBackground(false);
				realDistanceY = offsetY - oldOffsetY;
				offsetY +=mapChipHeight;
			}
			else{
				offsetY = 0;
				realDistanceY = offsetY - oldOffsetY;
			}
		}

		if(offsetX + mapViewWidth > mapChipWidth * mapChipNumX){
			if(currentChipX + mapChipNumX < mapChipTotalX){
				currentChipX++;
				updateMapBackground(false);
				realDistanceX = offsetX - oldOffsetX;
				offsetX -= mapChipWidth;
			}
			else{
				offsetX = mapChipWidth * mapChipNumX - mapViewWidth;
				realDistanceX = offsetX - oldOffsetX;
			}
		}
		
		if(offsetY + mapViewHeight > mapChipHeight * mapChipNumY){
			if(currentChipY + mapChipNumY < mapChipTotalY){
				currentChipY++;
				updateMapBackground(false);
				realDistanceY = offsetY - oldOffsetY;
				offsetY -= mapChipHeight;
			}
			else{
				offsetY = mapChipHeight * mapChipNumY - mapViewHeight;
				realDistanceY = offsetY - oldOffsetY;
			}
		}
				
		oldOffsetX = offsetX;
		oldOffsetY = offsetY;
		Rect src = new Rect(offsetX, offsetY, offsetX + mapViewWidth, offsetY + mapViewHeight);
		Rect dst = new Rect(0, 0, mapViewWidth, mapViewHeight);
		c.drawBitmap(mapBackground, src, dst, null);
		
		holder.unlockCanvasAndPost(c);
	}

	private void updateMapBackground(boolean flag){
		if(flag){
			mapChipNumX = mapViewWidth / mapChipWidth + 2;
			if(mapChipNumX > mapChipTotalX){
				mapChipNumX = mapChipTotalX;
			}
			mapChipNumY = mapViewHeight / mapChipHeight + 2;
			if(mapChipNumY > mapChipTotalY){
				mapChipNumY = mapChipTotalY;
			}
		}
//		System.out.println(mapChipNumX + " : " + mapChipNumY);
		
		mapBackground = Bitmap.createBitmap(mapChipWidth * mapChipNumX, mapChipHeight * mapChipNumY, Config.ARGB_8888);
		Canvas cv = new Canvas(mapBackground);
		for(int i = 0; i < mapChipNumX; i++){
			for(int j = 0; j < mapChipNumY; j++){
				bm = getLoacalBitmap(mainDataPath + "/" + mapChipName[currentChipX + i][currentChipY + j]);
				cv.drawBitmap(bm, mapChipWidth * i, mapChipHeight * j, null);
			}
		}

	}
	
	private void initMapChip(){
		for(int i = 0; i < mapChipTotalY; i++){
			for(int j = 0; j < mapChipTotalX; j++){
				mapChipName[j][i] = "slice" + String.valueOf(i + 1) + "_" + String.valueOf(j + 1) + ".png"; 
			}
		}
	}
	
	public static Bitmap getLoacalBitmap(String url) {
        try {
             FileInputStream fis = new FileInputStream(url);
             return BitmapFactory.decodeStream(fis);  ///把流转化为Bitmap图片         

          } catch (FileNotFoundException e) {
             e.printStackTrace();
             return null;
        }
   }

	public void moveBy(int distanceX, int distanceY){
		realDistanceX = distanceX;
		realDistanceY = distanceY;
		offsetX = offsetX + distanceX;
		offsetY = offsetY + distanceY;
	}
}
